import { _decorator, Camera, Component, director, EventTouch, find, geometry, instantiate, Node, physics, PhysicsSystem, RigidBody, Vec3, Animation } from 'cc';
import { LBlockADsorptionEffect } from './LBlockADsorptionEffect';
import { GridController } from './GridController';
import ChessboardState from './ChessboardState';
import { Block } from './Block';
import { EventConst } from './EvenetConst';
import EventBus from './EventBus';
import { AssetMag } from './AssetMag';
const { ccclass, property } = _decorator;

@ccclass('Main')
export class Main extends Component {
    /**左上角圆角 */
    @property(Node) public Layer2d: Node;

    /**左上角圆角 */
    @property(GridController) public gridController: GridController;
    start() {


        this.Layer2d.on(Node.EventType.TOUCH_START, this.touchStart, this);
        this.Layer2d.on(Node.EventType.TOUCH_MOVE, this.touchMove, this);
        this.Layer2d.on(Node.EventType.TOUCH_END, this.touchEnd, this);
        this.Layer2d.on(Node.EventType.TOUCH_CANCEL, this.touchEnd, this);


        //监听色块单个事件
        EventBus.on(EventConst.PrepareClickEliminationBlock, this.onPrepareClickEliminationBlock, this);
        //监听消除多个相同色块事件
        EventBus.on(EventConst.PrepareClickEliminationBlockColor, this.onPrepareClickEliminationBlockColor, this);

    }

    protected onDestroy(): void {
        EventBus.off(EventConst.PrepareClickEliminationBlock, this.onPrepareClickEliminationBlock, this);
        EventBus.off(EventConst.PrepareClickEliminationBlockColor, this.onPrepareClickEliminationBlockColor, this);
    }



    /**
     * 基础的缩放因子
     */
    baseScale: number = 0.6;

    /**
     *最小缩放因子
     */
    minScale: number = 0.1;

    /**
     * 移动阈值
     */
    moveThreshold: number = 0.7;

    touchCurModelNode: Node;
    touchStart(event: EventTouch) {
        const originPos = event.getLocation();
        let ray = new geometry.Ray();
        find('Main Camera').getComponent(Camera).screenPointToRay(originPos.x, originPos.y, ray);

        let mask = 1 << 1;
        let maxDistance = 1000;
        let queryTrigger = false;
        if (PhysicsSystem.instance.raycastClosest(ray, mask, maxDistance, queryTrigger)) {
            let result = PhysicsSystem.instance.raycastClosestResult;
            console.log(result)


            if (result.collider.node.name.includes('Block')) {
                this.touchCurModelNode = result.collider.node;
                //start 单个颜色消除
                if (this.isPrepareClickEliminationBlock) {
                    this.getPrefabNode('Hammer')
                        .then(node => {
                            node.parent = director.getScene();
                            node.setWorldPosition(this.touchCurModelNode.worldPosition);
                            node.getChildByName('VFXBua').getComponent(Animation).play()
                            node.getChildByName('VFXBua').getComponent(Animation).once(Animation.EventType.LASTFRAME, () => {

                                // this.HammerNode.active = false;
                                node.getChildByName('VFXBua').getComponent(Animation).stop();
                                this.isPrepareClickEliminationBlock = false;
                                // node.getChildByName('VFXBua').getComponent(Animation).play();

                                EventBus.emit(EventConst.EliminationEnd);
                                this.touchCurModelNode.destroy();
                                this.touchCurModelNode = null;
                            }, node.getChildByName('VFXBua').getComponent(Animation))
                        })
                    return;
                }
                // 单个颜色消除

                //start 相同色块消除
                if (this.isPrepareClickEliminationBlockColor) {
                    this.getPrefabNode('Magnet')
                        .then(node => {
                            node.active = true;
                            node.parent = director.getScene();
                            node.setWorldPosition(this.touchCurModelNode.worldPosition);
                            node.getChildByName('VFXMagnet').getComponent(Animation).play()
                            node.getChildByName('VFXMagnet').getComponent(Animation).once(Animation.EventType.LASTFRAME, () => {
                                // this.HammerNode.active = false;
                                node.getChildByName('VFXMagnet').getComponent(Animation).stop();
                                // this.touchCurModelNode.destroy();
                                // this.touchCurModelNode = null;
                                let levelNode = this.touchCurModelNode.parent;
                                levelNode.children.forEach((child) => {
                                    // 消除同色
                                    if (child.getComponent(Block) && child.getComponent(Block).modelColor === this.touchCurModelNode.getComponent(Block).modelColor) {
                                        child.destroy();
                                    }
                                })
                                this.isPrepareClickEliminationBlockColor = false;
                                this.touchCurModelNode.destroy();
                                this.touchCurModelNode = null;
                                EventBus.emit(EventConst.EliminationEnd);
                            }, node.getChildByName('VFXMagnet').getComponent(Animation))
                            // node.getChildByName('VFXMagnet').getComponent(Animation).play();

                            // node.setWorldPosition(this.touchCurModelNode.worldPosition);


                        })

                    return;
                }
                //相同色块消除结束

                const screenPos = event.touch.getLocation();
                const camera = find('Main Camera').getComponent(Camera);
                const currentTocuhWordNode = new Vec3();
                camera.screenToWorld(new Vec3(screenPos.x, screenPos.y, 0), currentTocuhWordNode);

                this.lastTouchWordPos.set(currentTocuhWordNode);
                this.configureRigidBodyForDrag(this.touchCurModelNode.getComponent(RigidBody))
            }

        }
    }
    //start 准备点击block状态启停
    isPrepareClickEliminationBlock: boolean = false;
    onPrepareClickEliminationBlock() {
        this.isPrepareClickEliminationBlock = true;
    }
    isPrepareClickEliminationBlockColor: boolean = false;
    onPrepareClickEliminationBlockColor() {
        this.isPrepareClickEliminationBlockColor = true;
    }
    //end 准备点击block状态启停


    configureRigidBodyForDrag(blockRigidBody: RigidBody) {
        blockRigidBody.type = physics.ERigidBodyType.DYNAMIC;
        blockRigidBody.useGravity = false;

        //禁用旋转
        blockRigidBody.angularFactor = new Vec3(0, 0, 0);
        blockRigidBody.angularDamping = 0;

        //禁用阻尼
        blockRigidBody.linearDamping = 1;
        blockRigidBody.angularDamping = 1;

        //限制Y轴移动
        blockRigidBody.linearFactor = new Vec3(1, 0, 1);
        blockRigidBody.angularFactor = new Vec3(0, 0, 0);

    }

    lastTouchWordPos: Vec3 = new Vec3();
    touchMove(event: EventTouch) {

        //start 执行增加多重判断限制
        if (!this.touchCurModelNode ||
            !this.touchCurModelNode.isValid) return;

        //使用道具时不能处理移动相关逻辑
        if (this.isPrepareClickEliminationBlockColor
            || this.isPrepareClickEliminationBlock) {
            return;
        }
        //end  执行增加多重判断限制

        const screenPos = event.touch.getLocation();
        const camera = find('Main Camera').getComponent(Camera);
        const currentTocuhWordNode = new Vec3();
        camera.screenToWorld(new Vec3(screenPos.x, screenPos.y, 0), currentTocuhWordNode);

        if (this.lastTouchWordPos.equals(Vec3.ZERO)) {
            this.lastTouchWordPos.set(currentTocuhWordNode);
        }

        const moveDirection = new Vec3();
        Vec3.subtract(moveDirection, currentTocuhWordNode, this.lastTouchWordPos);

        if (!moveDirection.equals(Vec3.ZERO)) {
            let moveDistance = moveDirection.length();
            let dynamicScale = this.calcDynamicScale(moveDistance);
            this.touchCurModelNode.setWorldPosition(
                this.touchCurModelNode.getWorldPosition().x + moveDirection.x * dynamicScale,
                this.touchCurModelNode.getWorldPosition().y,
                this.touchCurModelNode.getWorldPosition().z + moveDirection.z * dynamicScale,
            )
        }


        this.lastTouchWordPos.set(currentTocuhWordNode);
        this.updateChessBoardState(this.touchCurModelNode.name);
    }

    getTouchCurModelNodeTileIndex() {
        return new LBlockADsorptionEffect(
            this.touchCurModelNode.getWorldPosition(),
            this.gridController.getTileList(),
            this.gridController.getTopRightPos()
        ).calcBlockChekerBoardPos(this.touchCurModelNode.getComponent(Block).blockDirection)
    }

    updateChessBoardState(name) {
        let indexs = this.getTouchCurModelNodeTileIndex();
        ChessboardState.clearValue(name);
        indexs.forEach(item => {
            ChessboardState.setBoard(item.x, item.z, name)
        })
    }

    calcDynamicScale(moveDistance: number): number {
        if (moveDistance <= this.moveThreshold) {
            return this.baseScale
        } else {
            const scale = this.baseScale * this.moveThreshold / moveDistance;
            return Math.max(scale, this.minScale)
        }
    }

    touchEnd() {
        if (!this.touchCurModelNode || !this.touchCurModelNode.isValid) return;
        if (this.isPrepareClickEliminationBlockColor || this.isPrepareClickEliminationBlock) {
            return;
        }
        console.log('设置位置2')
        let pos = new LBlockADsorptionEffect(
            this.touchCurModelNode.getWorldPosition(),
            this.gridController.getTileList(),
            this.gridController.getTopRightPos()
        ).calcBlockWordPos();
        this.touchCurModelNode.setWorldPosition(pos)
        this.updateChessBoardState(this.touchCurModelNode.name);
        this.touchCurModelNode.getComponent(RigidBody).type = physics.ERigidBodyType.KINEMATIC;
        this.touchCurModelNode.getComponent(RigidBody).setLinearVelocity(Vec3.ZERO)
        this.touchCurModelNode = null;


    }
    getPrefabNode(name: string): Promise<Node> {
        return new Promise((resolve, reject) => {
            AssetMag.loadPrefab(name)
                .then((prefab) => {
                    resolve(instantiate(prefab));
                })
                .catch((error) => {
                    reject(error);
                });
        });
    }

    update(deltaTime: number) {

    }
}


